﻿using System.Linq.Expressions;
using Glue.Internals.Nulls;

namespace Glue.Internals
{
    internal class LambdaDecomposer
    {
        private readonly LambdaExpression lambda;
        private Maybe<CompiledExpression> getNestedParentObject = Maybe<CompiledExpression>.Nothing();
        private GenericExpression genericExpression;

        public bool IsNestedProperty{ get { return getNestedParentObject.HasValue(); } }

        public LambdaDecomposer(LambdaExpression lambda)
        {
            this.lambda = lambda;
            Strip();
        }

        private void Strip()
        {
            var expression = lambda.Body;
            if (expression.NodeType == ExpressionType.Convert)
                expression = ((UnaryExpression)expression).Operand;
            genericExpression = new GenericExpression(expression);
            if (genericExpression.SubExpression.NodeType != ExpressionType.Parameter)
                getNestedParentObject = new Maybe<CompiledExpression>(new CompiledExpression(genericExpression.SubExpression));

        }

        public IObjectMemberAccessor GetAccessor()
        {
            return genericExpression.Accessor;
        }

        /// <summary>
        /// This only has value if this represents a nested property. Check IsNestedProperty first!
        /// </summary>
        public CompiledExpression GetNestedParentObjectGetter()
        {
            return getNestedParentObject.GetValue();
        }
    }
}
